package com.example.myutil;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;


public class FileUtilsExt extends FileUtilCopy {

	/**
	 * bytes转换为 KB MB GB,带小数，默认默认两位小数
	 * @param size
	 * @return
	 */
	public static String byteCountToDisplaySizeWithDecimal(Long size){
		return byteCountToDisplaySizeWithDecimal(BigInteger.valueOf(size),2);
	}
	
	/**
	 * bytes转换为 KB MB GB,带小数
	 * @param size
	 * @param decimal 小数位数
	 * @return
	 */
	public static String byteCountToDisplaySizeWithDecimal(BigInteger size,int decimal) {
		String displaySize = null;
		//除数
		BigInteger divisor = null;
		//单位
		String unitStr = null;
		if(decimal < 1){
			displaySize = byteCountToDisplaySize(size);
		}else if(size != null){
			if (size.divide(ONE_EB_BI).compareTo(BigInteger.ZERO) > 0) {
				divisor = ONE_EB_BI;
				unitStr = "EB";
			} else if (size.divide(ONE_PB_BI).compareTo(BigInteger.ZERO) > 0) {
				divisor = ONE_PB_BI;
				unitStr = "PB";
			} else if (size.divide(ONE_TB_BI).compareTo(BigInteger.ZERO) > 0) {
				divisor = ONE_TB_BI;
				unitStr = "TB";
			} else if (size.divide(ONE_GB_BI).compareTo(BigInteger.ZERO) > 0) {
				divisor = ONE_GB_BI;
				unitStr = "GB";
			} else if (size.divide(ONE_MB_BI).compareTo(BigInteger.ZERO) > 0) {
				divisor = ONE_MB_BI;
				unitStr = "MB";
			} else if (size.divide(ONE_KB_BI).compareTo(BigInteger.ZERO) > 0) {
				divisor = ONE_KB_BI;
				unitStr = "KB";
			} else {
				divisor = BigInteger.valueOf(1);
				unitStr = "bytes";
			}
			BigDecimal dSize = BigDecimal.valueOf(size.longValue());
			BigDecimal dDivisor = BigDecimal.valueOf(divisor.longValue());
			BigDecimal result = dSize.divide(dDivisor, decimal,RoundingMode.HALF_UP);
			String numberStr = String.valueOf(result);
			int length = numberStr.length();
			while(length >-1){
				//去掉数字多余的 0 和小数点
				boolean isSub = numberStr.endsWith("0") && numberStr.contains(".");
				isSub = isSub || numberStr.endsWith(".");
				if(isSub){
					numberStr = numberStr.substring(0, numberStr.length()-1);
				}
				length--;
			}
			displaySize = numberStr+" "+unitStr;
		}
		return displaySize;
	}

}

/**
 * org.apache.commons.io.FileUtils 的拷贝，避免 common-io 与 有赞 open-sdk-java 冲突问题
 *
 *
 */
class FileUtilCopy{
	 /**
     * The number of bytes in a kilobyte.
     */
    protected static final long ONE_KB = 1024;

    /**
     * The number of bytes in a kilobyte.
     * 
     * @since 2.4
     */
    protected static final BigInteger ONE_KB_BI = BigInteger.valueOf(ONE_KB);

    /**
     * The number of bytes in a megabyte.
     */
    protected static final long ONE_MB = ONE_KB * ONE_KB;

    /**
     * The number of bytes in a megabyte.
     * 
     * @since 2.4
     */
    protected static final BigInteger ONE_MB_BI = ONE_KB_BI.multiply(ONE_KB_BI);

    /**
     * The number of bytes in a gigabyte.
     */
    protected static final long ONE_GB = ONE_KB * ONE_MB;

    /**
     * The number of bytes in a gigabyte.
     * 
     * @since 2.4
     */
    protected static final BigInteger ONE_GB_BI = ONE_KB_BI.multiply(ONE_MB_BI);

    /**
     * The number of bytes in a terabyte.
     */
    protected static final long ONE_TB = ONE_KB * ONE_GB;

    /**
     * The number of bytes in a terabyte.
     * 
     * @since 2.4
     */
    protected static final BigInteger ONE_TB_BI = ONE_KB_BI.multiply(ONE_GB_BI);

    /**
     * The number of bytes in a petabyte.
     */
    protected static final long ONE_PB = ONE_KB * ONE_TB;

    /**
     * The number of bytes in a petabyte.
     * 
     * @since 2.4
     */
    protected static final BigInteger ONE_PB_BI = ONE_KB_BI.multiply(ONE_TB_BI);

    /**
     * The number of bytes in an exabyte.
     */
    protected static final long ONE_EB = ONE_KB * ONE_PB;

    /**
     * The number of bytes in an exabyte.
     * 
     * @since 2.4
     */
    protected static final BigInteger ONE_EB_BI = ONE_KB_BI.multiply(ONE_PB_BI);

    /**
     * The number of bytes in a zettabyte.
     */
    protected static final BigInteger ONE_ZB = BigInteger.valueOf(ONE_KB).multiply(BigInteger.valueOf(ONE_EB));

    /**
     * The number of bytes in a yottabyte.
     */
    protected static final BigInteger ONE_YB = ONE_KB_BI.multiply(ONE_ZB);
    
    //-----------------------------------------------------------------------
    /**
     * Returns a human-readable version of the file size, where the input represents a specific number of bytes.
     * <p>
     * If the size is over 1GB, the size is returned as the number of whole GB, i.e. the size is rounded down to the
     * nearest GB boundary.
     * </p>
     * <p>
     * Similarly for the 1MB and 1KB boundaries.
     * </p>
     * 
     * @param size
     *            the number of bytes
     * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes)
     * @see <a href="https://issues.apache.org/jira/browse/IO-226">IO-226 - should the rounding be changed?</a>
     * @since 2.4
     */
    // See https://issues.apache.org/jira/browse/IO-226 - should the rounding be changed?
    public static String byteCountToDisplaySize(BigInteger size) {
        String displaySize;

        if (size.divide(ONE_EB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(ONE_EB_BI)) + " EB";
        } else if (size.divide(ONE_PB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(ONE_PB_BI)) + " PB";
        } else if (size.divide(ONE_TB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(ONE_TB_BI)) + " TB";
        } else if (size.divide(ONE_GB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(ONE_GB_BI)) + " GB";
        } else if (size.divide(ONE_MB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(ONE_MB_BI)) + " MB";
        } else if (size.divide(ONE_KB_BI).compareTo(BigInteger.ZERO) > 0) {
            displaySize = String.valueOf(size.divide(ONE_KB_BI)) + " KB";
        } else {
            displaySize = String.valueOf(size) + " bytes";
        }
        return displaySize;
    }

    /**
     * Returns a human-readable version of the file size, where the input represents a specific number of bytes.
     * <p>
     * If the size is over 1GB, the size is returned as the number of whole GB, i.e. the size is rounded down to the
     * nearest GB boundary.
     * </p>
     * <p>
     * Similarly for the 1MB and 1KB boundaries.
     * </p>
     * 
     * @param size
     *            the number of bytes
     * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes)
     * @see <a href="https://issues.apache.org/jira/browse/IO-226">IO-226 - should the rounding be changed?</a>
     */
    // See https://issues.apache.org/jira/browse/IO-226 - should the rounding be changed?
    public static String byteCountToDisplaySize(long size) {
        return byteCountToDisplaySize(BigInteger.valueOf(size));
    }

}
